Using the Parallel port in QB
(and not for printing)


BACK

Introduction

On this page I will be describing how to use the parallel port to control your own electrical circuits. Why?, well, why not?. There are many uses for a circuit that can interface your programs to real-world objects. It would be used to control lights, monitor movement, etc. Personally, I constructed a computer controlled model railway (yes, I am aware of how geeky that is). The main purpose is to demonstrate just how easy it is to control or monitor something with the parallel port. When I first realized, I couldn't believe it. There are no complex decoder chips required or anything.
I will be giving examples of code in Qbasic. If you have already used the parallel port for such purposes, then don't bother reading this; I will only be covering the basics. First things first, this is nowhere near as difficult as you might expect, and the circuits required can have as little as two components.
But first, a warning:
It is possible that if you make a mistake, you computer will be damaged. Therefore, I would suggest that you do not experement with the parallel port on a computer you consider valuable. I also take no responsibility for either your mistakes, or any mistakes contained in on this page.
But if anyone does spot a mistake, particularly one that could lead to damage, then please email me at Anonymous101@Uncreativelabs.net
The first thing you need to do is find out the Address of you parallel port. For nearly all modern machines this is 378h (h = hexadecimal). If you are using an old herc graphics card (and the parallel port is on the graphics card) then the address is likely to be 3BCh. The pins required for output on the parallel port are pins 2 - 9. There are other pins that can be used for output, but they are harder to program; 8 outputs should be enough for now. Pins 10-13 and pin 14 can be used for input. Pins 18-25 are ground.

Wrinting to the output pins

From now on, i will call the first data pin (pin 2) d0, the second d1 and so on. The output pins have two states, high and low. You can toggle D0 (pin 2) high by writing 1 to the parrelel ports address. The following line of qbasic code will toggle the pin high:
OUT &h378, 1
To toggle D1 high you would write 2, for D2 you would write 4, D3 would be 8 and so on. To reset all of the data lines to low write 0, and to set all of the pins high write 255. If you want more than one pin high at the same time, then you add the data lines you want high together. For example, if you wanted D2 and D7 high you would use:
out &h378, 132		'(4 + 128)
To test this is working, the most basic circuit you can use is to simply to attach an LED to a 470 ohm resistor and connect it across pins 2 (D0) and 20 (ground). You would then be able to turn the LED on and off by writing a 1 or 0 to the port. If you want you could connect 8 LEDs to the port, and use it to test any programs you write.

Reading the Input pins

The command to read from ports in qbasic is INP. The address you need to read from is the address of the parallel port (usually 378h) + 1; so the usual address is 379h. As i mentioned before, the pins used for input are 10-13 and 15. Reading the different pins is little harder than writing to the ports, as you have to mask out the pins your not interested in. When you read the port, the first 3 bits returned are not used. For example, the qbasic code below would read pin 12 (out of paper). When this port is high, "Out of paper / pin 12 toggled" will be displayed:
data = inp(&h379)
IF (data and 32) = 32 then print "Out of paper / pin 12 high"
The table below list the pin input pin number, its normal purpose, and the number required to read it (eg 32 was used in the above example):
Pin Number Normal Purpose Number to read
10 Ackowledge 64
11 High when not Busy 128
12 High when out of paper 32
13 High when printer online 16
15 High when no error 8
If you understand binary, you should immediately see where these numbers are coming from, and why they are used to mask out all of the other pins we aren't trying to read. The simplest thing you can use to test this is to just connect a switch between an input pin and a ground pin (18-25). For example, if you connect a switch between pins 15 and 20, you could use the following code to monitor when the switch is pushed:
start:
res = INP(&H379)
CLS
IF (res AND 8) = 8 THEN PRINT "Button pushed" ELSE PRINT "Button NOT pushed"
FOR delay = 1 TO 500: NEXT delay
GOTO start
I know this code is a little messy, and will flicker, but it's written for clarity. The same code can be used to monitor the other four input lines by changing to the '8' to another number from the table.

Controlling a relay with the parallel port

The easiest way to use the parallel port to control higher-powered devices is to use a relay. A relay cannot be directly connected to the parallel port as it requires to much current (the parallel port only provides about 3ma), and the back emf could damage the port. Warning: Unlike the previous 'circuits', this one will need an external power supply; therefore there is a high chance that any mistakes will result in damage to the parallel port. The image below shows a circuit that could be used to control a relay:

The input voltage does not have to be 5v; it can be higher if required by the relay coil (up 24v). However, it is best to find a relay with a low coil voltage requirement if possible. A 12v relay could be used, it just increases the chances of damage to the computer if a mistake is made.
The relay can then be used to control almost any device (remember not to exceed the current/voltage for the relay contacts). As I mentioned at the beginning of this article, I used a few of these circuits to control a model railway.
Writing to the parallel port as described before can control this circuit. For example, if you connected this circuit to pins 2&25 (D0 & ground), you could activate the relay using this line of Qbasic code:
OUT &H378, 1
And deactivate it by:
OUT &H378, 0


Okay, I know this page has been very short and i've only described the absolute basics, but you should be able to see by now just how easy it would be to do far more complex things with the printer port. I will hopefully be exteding this page soon to include some more practical output circuits and code (if anyone's interested).
As another point, you could use the input code to actually monitor a printer (is it online, out of paper, etc..). Hmmm.... just had an idea for an interesting TSR.......

BACK